package com.siashan.unipay4j.wx.splitbill;

import com.alibaba.fastjson.JSON;
import com.siashan.unipay4j.core.IPayConfig;
import com.siashan.unipay4j.core.Result;
import com.siashan.unipay4j.core.exception.Unipay4jInvalidParamException;
import com.siashan.unipay4j.core.splitbill.*;
import com.siashan.unipay4j.core.util.MoneyUtil;
import com.siashan.unipay4j.wx.AbstractWxPay;
import com.siashan.unipay4j.wx.WxBizEnum;
import com.siashan.unipay4j.wx.sdk.WXPayConstants;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 微信分账
 *
 * @author  siashan
 * @version  V1.0.1
 **/
@Slf4j
public class WxPaySplitBill  extends AbstractWxPay implements ISplitBill {
    public WxPaySplitBill() {
    }

    public WxPaySplitBill(IPayConfig payConfig) {
        super(payConfig);
    }

    /**
     * 分账
     *
     * @param model   分账请求参数
     * @return        分账请求结果
     */
    @Override
    public Result<SplitBillResp> split(ProfitModel model) {
        log.debug("WxPaySplitBill => 订单{} 微信分账请求到达", model.getOutTradeNo());
        try {
            String requestUrl = ProfitType.SINGLE.equals(model.getProfitType()) ? WXPayConstants.PROFITSHARING_URL_SUFFIX : WXPayConstants.MULTIPROFITSHARING_URL_SUFFIX;
            Map<String, String> r = initWxPay().sendRequest(wrapParam(model),requestUrl, WxBizEnum.SPLITBILL, true);
            log.debug("WxPaySplitBill => 订单{} 微信分账请求返回报文:{}", model.getOutTradeNo(), r);
            String returnCode = getReturnCode(r);
            if (isReturnSuccess(returnCode)) {
                if (isResultSuccess(r)) {
                    log.debug("WxPaySplitBill => 订单{} 微信分账请求成功", model.getOutTradeNo());
                    return Result.tradeSuccess(wrapResp(r));
                } else {
                    String errCode = r.get(WXPayConstants.ERR_CODE);
                    String errCodeDes = r.get(WXPayConstants.ERR_CODE_DES);
                    log.info("WxPaySplitBill => 订单{} 微信分账请求返回失败,错误代码:{},错误描述:{}", model.getOutTradeNo(), errCode, errCodeDes);
                    return Result.returnFail(errCode, errCodeDes);
                }
            } else {
                String returnMsg = r.get(WXPayConstants.RETURN_MSG);
                log.info("WxPaySplitBill => 订单{} 微信分账请求通信失败,错误代码:{},错误描述:{}", model.getOutTradeNo(), returnCode, returnMsg);
                return Result.returnFail(returnCode, returnMsg);
            }

        } catch (Exception e) {
            log.warn("WxPaySplitBill => 订单{} 微信分账请求异常", model.getOutTradeNo(),e);
        }
        return Result.exception();
    }

    private SplitBillResp wrapResp( Map<String, String> r){
        SplitBillResp resp = new SplitBillResp();
        resp.setTradeNo(r.get("order_id"));
        resp.setOutTradeNo(r.get("out_order_no"));
        return resp;
    }


    private Map<String, String> wrapParam(ProfitModel model) {
        Map<String, String> map = new HashMap<>();
        List<Receiver> receivers = model.getReceivers();
        if (null == receivers || receivers.isEmpty()){
            throw new Unipay4jInvalidParamException("分账接受方不能为空");
        }

        List<WxReceiver> list = new ArrayList<>();
        WxReceiver wxReceiver = null;
        for (Receiver r : receivers){
            wxReceiver = new WxReceiver();
            wxReceiver.setAccount(r.getAccount());
            wxReceiver.setType(r.getType());
            wxReceiver.setAccount(String.valueOf(MoneyUtil.yuan2Cent(r.getAmount())));
            wxReceiver.setDescription(r.getDescription());
            list.add(wxReceiver);
        }
        map.put("transaction_id",model.getTradeNo());
        map.put("out_order_no",model.getOutTradeNo());
        map.put("receivers", JSON.toJSONString(list));
        return map;
    }
}
